package rpwd

import (
	"encoding/json"
	"fmt"
	"os"
	"sync"
)

const (
	AccMySQL      = "mysql"
	AccRedis      = "redis"
	AccMongoDB    = "mongo_db"
	AccSQLite     = "sqlite"
	AccOracle     = "oracle"
	AccSQLServer  = "sql_server"
	AccMariaDB    = "maria_db"
	AccPostgreSQL = "postgre_sql"
)

const (
	KeyJwtSecretKey = "jwt_secret_key" //jwt密钥
	KeyPwdSecretKey = "pwd_secret_key" //密码加密密钥
)

type password struct {
	AccountAndPassword map[string]AccountAndPassword `json:"account_and_password"` //账号和密码
	Keys               map[string]string             `json:"keys"`                 //密钥
	Other              map[string]any                `json:"other"`                //其它
}

type AccountAndPassword struct {
	IP       string `json:"ip"`       //IP
	Port     uint   `json:"port"`     //端口
	Account  string `json:"account"`  //账号
	Password string `json:"password"` //密码
	Other    string `json:"other"`    //其它
}

var _password password
var _passwordLock = sync.Mutex{}

// AutoSavePasswordFile 自动保存password文件，如果原来的里面有的key，则不作任何改动；不存在的key则新增。
func AutoSavePasswordFile(filepath string, accPwd map[string]AccountAndPassword, keys map[string]string, other map[string]any) error {
	if filepath == "" {
		return fmt.Errorf("save filepath == empty")
	}
	_passwordLock.Lock()
	defer _passwordLock.Unlock()
	file, err := os.ReadFile(filepath)
	if err == nil {
		_ = json.Unmarshal(file, &_password)
	}
	if _password.AccountAndPassword == nil {
		_password.AccountAndPassword = make(map[string]AccountAndPassword)
	}
	for k, v := range accPwd {
		if _, ok := _password.AccountAndPassword[k]; ok {
			continue
		}
		_password.AccountAndPassword[k] = v
	}
	if _password.Keys == nil {
		_password.Keys = make(map[string]string)
	}
	for k, v := range keys {
		if _, ok := _password.Keys[k]; ok {
			continue
		}
		_password.Keys[k] = v
	}
	if _password.Other == nil {
		_password.Other = make(map[string]any)
	}
	for k, v := range other {
		if _, ok := _password.Other[k]; ok {
			continue
		}
		_password.Other[k] = v
	}
	indent, err := json.MarshalIndent(&_password, "", "  ")
	if err != nil {
		return err
	}
	err = os.WriteFile(filepath, indent, 0660)
	return err
}

// LoadPasswordFile 加载password文件
func LoadPasswordFile(filepath string) error {
	_passwordLock.Lock()
	defer _passwordLock.Unlock()
	file, err := os.ReadFile(filepath)
	if err != nil {
		return err
	}
	err = json.Unmarshal(file, &_password)
	if err != nil {
		return err
	}
	return nil
}

// GetAccountAndPassword 获取指定name的账号和密码信息
func GetAccountAndPassword(name string) (AccountAndPassword, error) {
	_passwordLock.Lock()
	defer _passwordLock.Unlock()
	if _password.AccountAndPassword == nil {
		return AccountAndPassword{}, fmt.Errorf("未找到")
	}
	if v, ok := _password.AccountAndPassword[name]; ok {
		return v, nil
	}
	return AccountAndPassword{}, fmt.Errorf("未找到")
}

// GetKey 获取指定key的值
func GetKey(key string) (string, error) {
	_passwordLock.Lock()
	defer _passwordLock.Unlock()
	if _password.Keys == nil {
		return "", fmt.Errorf("未找到")
	}
	if v, ok := _password.Keys[key]; ok {
		return v, nil
	}
	return "", fmt.Errorf("未找到")
}

// GetOther 获取指定key的值
func GetOther(key string) (any, error) {
	_passwordLock.Lock()
	defer _passwordLock.Unlock()
	if _password.Other == nil {
		return nil, fmt.Errorf("未找到")
	}
	if v, ok := _password.Other[key]; ok {
		return v, nil
	}
	return nil, fmt.Errorf("未找到")
}
